<?php

declare(strict_types=1);
/**
 * This file is part of habo_new_media.
 *
 * @link     https://www.berlen.cn/
 * @contact  tech@berlen.cn
 * @license  http://gitlab.rehou.cn/habo/habo_new_media/-/blob/master/README.md
 */
namespace app\service\stat\cdc;

use app\model\mongo\MongoKsAccountDayReportModel;
use app\service\BaseService;
use app\service\client\AccountService;
use app\service\stat\StatModelInterface;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;

class KsAdvertiserCostStatService extends BaseService implements StatModelInterface
{
    /**
     * 获取广告账户流水信息.
     * @param string $advertiserId 账户ID
     * @param int $statDate 日期
     * @param array $params 表参数
     * @return null|array||mixed|Model
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public static function getStatInfo(string $advertiserId = '', int $statDate = 0, array $params = [])
    {
        $where = [
            ['adv_id', '=', $advertiserId],
            ['stat_date', '=', $statDate],
        ];
        return (new MongoKsAccountDayReportModel())->where($where)->find();
    }

    /**
     * 修改报表信息.
     * @param Model $model 表模型
     * @param array $params 表参数
     */
    public static function updateStatData(Model $model, array $params = []): bool
    {
        if (! $model instanceof MongoKsAccountDayReportModel) {
            return self::setError('报表模型错误');
        }
        try {
            // 更新为最新的信息
            $accountInfo = BaseService::getClientAccountInfo($model->getAttr('adv_id'));

            $balance = floatval($params['balance']);
            $dailyCharge = floatval($params['daily_charge']);
            $realCharged = floatval($params['real_charged']);
            $contractRebateRealCharged = floatval($params['contract_rebate_real_charged']);
            $directRebateRealCharged = floatval($params['direct_rebate_real_charged']);
            $dailyTransferIn = floatval($params['daily_transfer_in']);
            $realRecharged = floatval($params['real_recharged']);
            $contractRebateRealRecharged = floatval($params['contract_rebate_real_recharged']);
            $directRebateRealRecharged = floatval($params['direct_rebate_real_recharged']);
            $dailyTransferOut = floatval($params['daily_transfer_out']);
            $orderTotalCharged = floatval($params['order_total_charged']);
            $orderRealCharged = floatval($params['order_real_charged']);
            $orderContractCharged = floatval($params['order_contract_charged']);
            $orderDirectCharged = floatval($params['order_direct_charged']);

            // 主表
            $insertId = $model->strict(false)->where('_id', strval($model->getAttr('_id')))->save([
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'daily_charge' => $dailyCharge,
                'real_charged' => $realCharged,
                'contract_rebate_real_charged' => $contractRebateRealCharged,
                'balance' => $balance,
                'direct_rebate_real_charged' => $directRebateRealCharged,
                'daily_transfer_in' => $dailyTransferIn,
                'real_recharged' => $realRecharged,
                'contract_rebate_real_recharged' => $contractRebateRealRecharged,
                'direct_rebate_real_recharged' => $directRebateRealRecharged,
                'daily_transfer_out' => $dailyTransferOut,
                'order_total_charged' => $orderTotalCharged,
                'order_real_charged' => $orderRealCharged,
                'order_contract_charged' => $orderContractCharged,
                'order_direct_charged' => $orderDirectCharged,
                'is_sync' => MongoKsAccountDayReportModel::SYNC_FAIL,
                'update_time' => time(),
                'content' => $params,
            ]);
            if ($insertId <= 0) {
                return self::setError('修改报表信息失败');
            }

            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 修改报表信息.
     * @param Model $model 表模型
     * @param array $params 表参数
     */
    public static function updateReportData(Model $model, array $params = []): bool
    {
        if (! $model instanceof MongoKsAccountDayReportModel) {
            return self::setError('报表模型错误');
        }
        try {
            // 更新为最新的信息
            $accountInfo = BaseService::getClientAccountInfo($model->getAttr('adv_id'));

            $dailyCharge = floatval($params['charge']);

            // 主表
            $insertId = $model->strict(false)->where('_id', strval($model->getAttr('_id')))->save([
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'daily_charge' => $dailyCharge,
                'is_sync' => MongoKsAccountDayReportModel::SYNC_FAIL,
                'update_time' => time(),
                'content' => $params,
            ]);
            if ($insertId <= 0) {
                return self::setError('修改报表信息失败');
            }

            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 插入报表信息.
     * @param string $advertiserId 账户id
     * @param array $params 表参数
     */
    public static function insertStatData(string $advertiserId = '', array $params = []): bool
    {
        $difField = [
            'balance', 'daily_charge', 'real_charged', 'contract_rebate_real_charged', 'direct_rebate_real_charged', 'daily_transfer_in', 'real_recharged', 'contract_rebate_real_recharged', 'direct_rebate_real_recharged', 'daily_transfer_out', 'order_total_charged', 'order_real_charged', 'order_contract_charged', 'order_direct_charged',
        ];
        $hasData = false;
        foreach ($difField as $field) {
            if ($params[$field] > 0) {
                $hasData = true;
                break;
            }
        }
        if (! $hasData) {
            return true;
        }

        try {
            $accountInfo = BaseService::getClientAccountInfo($advertiserId);

            $statDate = intval(date('Ymd', strtotime($params['date'])));
            $statMonth = intval(date('Ym', strtotime($params['date'])));
            $balance = floatval($params['balance']);
            $dailyCharge = floatval($params['daily_charge']);
            $realCharged = floatval($params['real_charged']);
            $contractRebateRealCharged = floatval($params['contract_rebate_real_charged']);
            $directRebateRealCharged = floatval($params['direct_rebate_real_charged']);
            $dailyTransferIn = floatval($params['daily_transfer_in']);
            $realRecharged = floatval($params['real_recharged']);
            $contractRebateRealRecharged = floatval($params['contract_rebate_real_recharged']);
            $directRebateRealRecharged = floatval($params['direct_rebate_real_recharged']);
            $dailyTransferOut = floatval($params['daily_transfer_out']);
            $orderTotalCharged = floatval($params['order_total_charged']);
            $orderRealCharged = floatval($params['order_real_charged']);
            $orderContractCharged = floatval($params['order_contract_charged']);
            $orderDirectCharged = floatval($params['order_direct_charged']);

            $data = [
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'adv_id' => $advertiserId,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'product_id' => $accountInfo['product_id'] ?? 0,
                'stat_date' => $statDate,
                'stat_month' => $statMonth,
                'daily_charge' => $dailyCharge,
                'real_charged' => $realCharged,
                'contract_rebate_real_charged' => $contractRebateRealCharged,
                'balance' => $balance,
                'direct_rebate_real_charged' => $directRebateRealCharged,
                'daily_transfer_in' => $dailyTransferIn,
                'real_recharged' => $realRecharged,
                'contract_rebate_real_recharged' => $contractRebateRealRecharged,
                'direct_rebate_real_recharged' => $directRebateRealRecharged,
                'daily_transfer_out' => $dailyTransferOut,
                'order_total_charged' => $orderTotalCharged,
                'order_real_charged' => $orderRealCharged,
                'order_contract_charged' => $orderContractCharged,
                'order_direct_charged' => $orderDirectCharged,
                'project_id' => $accountInfo['project_id'] ?? 0,
                'staff_id' => $accountInfo['staff_id'] ?? 0,
                'is_sync' => MongoKsAccountDayReportModel::SYNC_FAIL,
                'source' => MongoKsAccountDayReportModel::SOURCE_FLOW,
                'create_time' => time(),
                'update_time' => time(),
                'content' => $params,
            ];
            $model = new MongoKsAccountDayReportModel();
            $id = $model->insertGetId($data);

            if ($id <= 0) {
                return self::setError('插入报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }

    /**
     * 对比数据是否相同.
     * @param Model $model 表模型
     * @param array $param 表参数
     */
    public static function isSame(Model $model, array $param = []): bool
    {
        $difField = [
            'balance', 'daily_charge', 'real_charged', 'contract_rebate_real_charged', 'direct_rebate_real_charged', 'daily_transfer_in', 'real_recharged', 'contract_rebate_real_recharged', 'direct_rebate_real_recharged', 'daily_transfer_out', 'order_total_charged', 'order_real_charged', 'order_contract_charged', 'order_direct_charged',
        ];

        // 验证数据是否相同
        foreach ($difField as $val) {
            if ($model->getAttr($val) != $param[$val]) {
                return false;
            }
        }

        // 判断账户是否已更新
        $accountInfo = AccountService::getAccountModel(0, strval($param['advertiser_id']));
        if ($accountInfo->getAttr('client_id') != $model->getAttr('client_id') || $accountInfo->getAttr('id') != $model->getAttr('account_id')) {
            return false;
        }
        return true;
    }

    /**
     * 插入报表信息.
     * @param string $advertiserId 账户id
     * @param array $params 表参数
     */
    public static function insertReportData(string $advertiserId = '', array $params = []): bool
    {
        try {
            $accountInfo = BaseService::getClientAccountInfo($advertiserId);

            $statDate = intval(date('Ymd', strtotime($params['stat_date'])));
            $statMonth = intval(date('Ym', strtotime($params['stat_date'])));
            $balance = 0;
            $dailyCharge = floatval($params['charge']);
            $realCharged = 0;
            $contractRebateRealCharged = 0;
            $directRebateRealCharged = 0;
            $dailyTransferIn = 0;
            $realRecharged = 0;
            $contractRebateRealRecharged = 0;
            $directRebateRealRecharged = 0;
            $dailyTransferOut = 0;
            $orderTotalCharged = 0;
            $orderRealCharged = 0;
            $orderContractCharged = 0;
            $orderDirectCharged = 0;

            $data = [
                'client_id' => $accountInfo['client_id'] ?? 0,
                'account_id' => $accountInfo['id'] ?? 0,
                'adv_id' => $advertiserId,
                'account_type' => $accountInfo['account_type'] ?? 0,
                'product_id' => $accountInfo['product_id'] ?? 0,
                'stat_date' => $statDate,
                'stat_month' => $statMonth,
                'daily_charge' => $dailyCharge,
                'real_charged' => $realCharged,
                'contract_rebate_real_charged' => $contractRebateRealCharged,
                'balance' => $balance,
                'direct_rebate_real_charged' => $directRebateRealCharged,
                'daily_transfer_in' => $dailyTransferIn,
                'real_recharged' => $realRecharged,
                'contract_rebate_real_recharged' => $contractRebateRealRecharged,
                'direct_rebate_real_recharged' => $directRebateRealRecharged,
                'daily_transfer_out' => $dailyTransferOut,
                'order_total_charged' => $orderTotalCharged,
                'order_real_charged' => $orderRealCharged,
                'order_contract_charged' => $orderContractCharged,
                'order_direct_charged' => $orderDirectCharged,
                'project_id' => $accountInfo['project_id'] ?? 0,
                'staff_id' => $accountInfo['staff_id'] ?? 0,
                'is_sync' => MongoKsAccountDayReportModel::SYNC_FAIL,
                'source' => MongoKsAccountDayReportModel::SOURCE_REPORT,
                'create_time' => time(),
                'update_time' => time(),
                'content' => $params,
            ];

            $model = new MongoKsAccountDayReportModel();
            $id = $model->insertGetId($data);

            if ($id <= 0) {
                return self::setError('插入报表信息失败');
            }
            return true;
        } catch (\Exception $e) {
            return self::setError($e->getMessage());
        }
    }
}
